package com.hxkcloud.patient.aerotel.service;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;


import com.hxkcloud.patient.YjhApplication;
import com.hxkcloud.patient.aerotel.AerotelActivity;
import com.hxkcloud.patient.aerotel.domain.health.AerotelECGPdu;
import com.hxkcloud.patient.aerotel.domain.health.HealthDeviceManager;
import com.hxkcloud.patient.aerotel.log.AppLogger;
import com.hxkcloud.patient.aerotel.notification.HDCNotification;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.UUID;

/**
 * Created by daipengfei on 16/3/3.
 * 接受心电设备发送的数据
 */
public class AerotelECGReceiveService extends Service {

    private final static int WHAT_NOPAIRDEVICE = -1;
    private final static int WHAT_PAIRING = 0;
    private final static int WHAT_LISTENING = 1;
    private final static int WHAT_RECEIVING = 2;
    private final static int WHAT_RECEIVED = 3;
    private static final String TAG = AerotelECGReceiveService.class.getSimpleName();

    private Context context;
    private ServerThread server;


    private BroadcastReceiver state = new BroadcastReceiver() {//监听蓝牙打开
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                switch (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0)) {
                    case BluetoothAdapter.STATE_OFF://蓝牙关闭
                        AerotelECGReceiveService.this.stopSelf();
                        break;
                }

            }
        }
    };
    @Override
    public void onCreate() {
        super.onCreate();
        context = this.getApplicationContext();
        registerReceiver(state, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
        if (HDCNotification.getHDCNotification() == null) {
            HDCNotification hdcn = new HDCNotification(context);
            HDCNotification.hdcnotification = hdcn;
        }
    }

    @Override
    public void onDestroy() {
        if (server != null) {
            server.interrupt();
        }
        AerotelECGReceiveService.this.unregisterReceiver(state);
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        server = new ServerThread();
        server.start();//开启服务线程
        return START_NOT_STICKY/*super.onStartCommand(intent, flags, startId)*/;
    }

    public Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (HDCNotification.hdcnotification != null) {
                String text = "";
                switch (msg.what) {
                    case WHAT_NOPAIRDEVICE:
                        text = "未找到配对心电设备";
                        HDCNotification.hdcnotification.notify(text, -1);
                    case WHAT_PAIRING:
                        text = "正在查找心电设备 ...";
                        HDCNotification.hdcnotification.notify(text, -1);
                        break;
                    case WHAT_LISTENING:
                        text = "服务工作正常";
                        HDCNotification.hdcnotification.notify(text, -1);
                        break;
                    case WHAT_RECEIVING:
                        int progress = msg.getData().getInt("progress", 0);
                        AppLogger.i("" + progress);
                        HDCNotification.hdcnotification.notify(progress);
                        break;
                    case WHAT_RECEIVED:
                        HDCNotification.hdcnotification.notify("成功接收心电图");
                        break;
                    default:
                        break;
                }
            }
            super.handleMessage(msg);
        }
    };

    public class DiscoverThread extends Thread {

        private boolean running = false;

        public DiscoverThread() {
        }

        @Override
        public void run() {

        }
    }

    /**
     * 服务线程
     */
    public class ServerThread extends Thread {

        private boolean running = true;
        private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//特定的UUID

        private BluetoothDevice target = null;// socket连接的对象
        private BluetoothServerSocket serverSocket;
        private BluetoothSocket socket = null;// bt socket对象

        public ServerThread() {
//            target = device;
        }

        public ServerThread(BluetoothDevice device) {
            target = device;
        }

        public void run() {
            try {
                Log.e("CREATE BT SOCKET", "creating bt socket");
                /**
                 * 蓝牙socket连接的建立
                 */

                while (running) {
                    try {
                        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
                        if (adapter.isEnabled()){
                            serverSocket = adapter.listenUsingRfcommWithServiceRecord("Android HVP Receiver", uuid);
                            Message msg = AerotelECGReceiveService.this.handler.obtainMessage();
                            msg.what = WHAT_LISTENING;
                            msg.sendToTarget();
                            if (serverSocket!=null){
                                socket = serverSocket.accept(600000);//设置超时的时间
                            }
                        }else {
                            continue;
                        }
                    } catch (IOException ex) {
                        AppLogger.e("accpect exception", ex);
                        continue;
                    }

                    BluetoothDevice rdevice = socket.getRemoteDevice();
                    if (!HealthDeviceManager.exists(rdevice)) {
                        continue;
                    }
                    if (socket == null)
                        return;
                    byte[] buf = new byte[60];
                    InputStream is = socket.getInputStream();
                    OutputStream os = socket.getOutputStream();

                    Log.e("creating success", "create bt socket success");


                    //  核心接受代码   前六十个字节是蓝牙信息的头。
                    try {
                        Message msg = AerotelECGReceiveService.this.handler.obtainMessage();
                        msg.what = WHAT_RECEIVING;
                        msg.getData().putInt("progress", 0);
                        msg.sendToTarget();

                        AerotelECGPdu pdu = new AerotelECGPdu();
                        int hp = 0;
                        while (hp < 60) {//读取蓝牙头信息
                            //只要没有够60个字节一直会读
                            int len = is.read(buf, hp, 60 - hp);
                            hp += len;
                            AppLogger.d(String.valueOf(len));
                        }
                        if (hp == 60) {
                            byte[] h = Arrays.copyOfRange(buf, 0, hp);//蓝牙头信息
                            pdu.header = new AerotelECGPdu.Header(h);
                            byte[] bytes = new byte[1];

                            bytes[0] = AerotelECGPdu.BT_STX;//开始传输
                            os.write(bytes);
                            os.flush();
                            int retry = 6;//重试六次
                            while ((retry--) > 0) {
                                h = new byte[14740];//总共的报文数量
                                int p = 0;
                                while (p < 14740) {
                                    int len = is.read(h, p, 14740 - p);
                                    p += len;
                                    AppLogger.i(String.valueOf(p));
                                    int progress = p * 100 / 14740;
                                    msg = AerotelECGReceiveService.this.handler.obtainMessage();
                                    msg.what = WHAT_RECEIVING;
                                    Bundle bundle = msg.getData();
                                    bundle.putInt("progress", progress);
                                    msg.setData(bundle);
                                    msg.sendToTarget();

                                    if(YjhApplication.aerotelActivity != null){
                                        msg = YjhApplication.aerotelActivity.handler.obtainMessage();
                                        msg.what = AerotelActivity.WHAT_RECEIVE_PROGRESS_UPDATE;
                                        msg.getData().putInt("progress", progress);
                                        msg.sendToTarget();
                                    }
                                }
                                //校验数据最后都要去除
                                pdu.data = new AerotelECGPdu.Data(h);
                                if (pdu.data.checksum()) {    //校验
                                    os.write(AerotelECGPdu.BT_ETX);//告诉设备收完了
                                    Log.e(TAG,"告诉设备收完了");
                                    os.flush();
                                    // Save PDU to LocalStorage
                                    pdu.devicename = rdevice.getName();
                                    pdu.devicebtmac = rdevice.getAddress();
                                    pdu.save2local(context);
                                    msg = AerotelECGReceiveService.this.handler.obtainMessage();
                                    msg.what = WHAT_RECEIVED;
                                    msg.sendToTarget();//发信号给控制栏

                                    if(YjhApplication.aerotelActivity != null){//发消息给主页面
                                        msg =YjhApplication.aerotelActivity.handler.obtainMessage();
                                        msg.what = AerotelActivity.WHAT_ECG_REFRESH;
                                        msg.sendToTarget();
                                    }
                                } else {
                                    os.write(AerotelECGPdu.BT_NAK);//重传
                                    os.flush();
                                    Log.e(TAG,"删除设备上的数据");
                                }
                            }
                        }
                    } catch (Exception e) {
                        // Log.e("Exception","receive bt socket data exception");
                        AppLogger.e(e.getMessage());
                    } finally {
                        os.write(AerotelECGPdu.BT_ETX);
                        os.flush();
                        if (os!=null){
                            os.close();
                        }
                        if (is!=null){
                            is.close();
                        }
                        closeSocket();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                AppLogger.e(e.getMessage());
            } finally {
                if (serverSocket != null) {
                    try {
                        serverSocket.close();
                        serverSocket = null;
                        running = false;
                    } catch (IOException e) {
                        AppLogger.e(e.getMessage());
                    }
                }
                AerotelECGReceiveService.this.stopSelf();
            }
        }

        private void closeSocket() {
            if (this.socket == null) {
                return;
            }
            try {
                socket.close();
                System.out.println("closing bt socket");
            } catch (IOException e) {
                AppLogger.e(e.getMessage());
            }
            socket = null;
        }
    }
}
